// ==UserScript==
// @name         采集表统计助手
// @namespace    http://xg.mediportal.com.cn/
// @version      0.4
// @description  数字化营销临床调研采集表统计助手
// @author       Waylon Wang
// @match        *://xg.mediportal.com.cn/ysf-case-pc/*
// @icon         http://drug.file.mediportal.com.cn/o_1c461pmm3e265k1a6m19qccso1r
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function () {
    'use strict';
    /* 
     * ================== 显示操作 ==================
     */
    let css = `

  .switch-button {
    position: fixed;
    top: 2px;
    left: 2px;
    z-index: 9999;
    width: 26px;
    height: 26px;
    border-radius: 20px;
    cursor: pointer;
    filter: brightness(100%);
    transition: filter 0.3s ease;
  }

  .switch-button:hover {
    filter: brightness(90%);
  }

  .data-panel, .detail-panel{
    position: fixed;
    background-color: white;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
    border-radius: 15px;
    color: #cccccc;
    display: flex;
  }

  
  .data-panel {
    top: 0px;
    left: 0px;
    z-index: 9998;
    transition: width 0.5s ease-in-out,height 0.5s ease-in-out, border-radius 0.5s ease;
  }

  .detail-panel {
    top: 0px;
    left: 410px;
    min-width: 200px;
    min-height: 100px;     
    border-radius: 5px;
    z-index: 10000;
    transition: width 0.5s ease-in-out,height 0.5s ease-in-out, border-radius 0.5s ease, opacity 0.5s ease;
  }

  .data-panel-collapse {
    width: 30px;
    height: 30px;
    border-radius: 15px;
  }

  .data-panel-expand {
    min-width: 400px;
    min-height: 150px;
    border-radius: 5px;
  }

  .projects-panel, .project-panel {
    width: 100%;
    height: 100%;
    opacity: 1; /* 默认可见状态 */
    transition: width 0.5s ease-in-out,height 0.5s ease-in-out, opacity 0.5s ease; /* 添加过渡效果 */
    pointer-events: auto;
    display: block;
    padding: 0px 10px 10px 10px;
  }

  .projects-panel-hidden {
    opacity: 0; /* 隐藏状态 */
    pointer-events: none; /* 在元素隐藏时避免鼠标事件 */
  }

  .update-container, .name-container{
    display: inline-flex;
    width: 100%;
    height: 35px;
    flex-direction: row-reverse;    
  }

  .update-container #time, .name-container #project {
    position: relative;
    font-size: 12px;
    height: 23px;
    margin: 5px;
    padding: 5px;
  }

  .update-container #button {
    position: relative;
    font-size: 12px;
    height: 23px;
    margin: 5px 0px;
    padding: 5px 20px;
  }

  .name-container #project {
    width: 100%;
  }

  .name-container #close {
    position: relative;
    font-size: 14px;
    height: 23px;
    margin: 5px 0px;
    padding: 5px 5px;
    cursor: pointer;
  }

  .detail-list {
    padding: 0px;
    overflow: auto;
    max-width: 1000px;
    max-height: 800px;        
  }

  .project-item, .detail-item{
    display: flex;
    color: #666666;      
  }

  .detail-item {
    width: fit-content; 
    margin: 1px;
  }

  .project-item:not(.projects-title):hover, .detail-item:not(.detail-title,.detail-total):hover{
    background-color: #e2f2ff;
    color: #409eff;      
  }

  .project-item div, .detail-item div{
    margin: 5px 5px;
    padding: 2px;
    font-size: 12px; 
    text-align: right;
    justify-content: right;
    align-items: center;
    display: flex;    
  }

  .project-item #name{
    width: 80px;
    font-weight: bold;
  }
  
  .detail-item #period {
    justify-content: left;
    width: 100px;
  }

  .detail-item #sum{
    width: 80px;
  }

  .project-item #total, .project-item #remaining, .project-item #checked{
    width: 25%;
  }

  .projects-title, .detail-title {
    color: #999999;
    font-weight: bold;
    border-bottom: 1px dashed #cccccc;
  }  

  .detail-total {
    color: #999999;
    font-weight: bold;
    border-top: 1px dashed #cccccc;
  }  

  .progress-bar{
    width: 100%;
    height: 10px;
    background-color: #eeeeee;
    overflow: hidden;
    position: relative;
    padding: 0px!important;
    margin: 0px!important;
  }

  .progress-indicator{
    width: 0%;
    height: 100%;
    background-color: #2fd85f;
    position: absolute;
    top: 0;
    left: 0;
    padding: 0px!important;
    margin: 0px!important;
  }

  .checked-count{
    text-decoration: underline;
    width: 100%;
    height: 100%;
    padding: 0px!important;
    margin: 0px!important;
    cursor: pointer;
  }

  .detail-item-cell {
    width: 60px;
  }

  .period-month {
    background-color: #f0f0f0;
  }

  .period-month #period:after{
    content: '月';
  } 

  .period-week {
    background-color: #f8f8f8;
  }

  .period-week #period{
    text-indent: 10px;
  } 

  .period-week #period:after{
    content: '周';
    margin-left: -10px;
  } 

  .period-day {
    background-color: #ffffff;
  }

  .period-day #period{
    text-indent: 20px;
  } 

  .not-expand{
    cursor: cell;
    font-weight: bold;
  }

      `;

    // 注入CSS
    (css => {
        let styleElement = document.createElement('style');
        styleElement.type = 'text/css';
        styleElement.textContent = css;
        document.head.appendChild(styleElement);
    })(css);

    // 显示数据面板
    function showPanel() {
        let switchButton = document.createElement('img');
        let dataPanel = document.createElement('div');
        let projectsPanel = document.createElement('div');
        let updateContainer = document.createElement('div');
        let updateTime = document.createElement('div');
        let updateButton = document.createElement('div');
        let projectsTitle = document.createElement('div');
        let titleName = document.createElement('div');
        let titleTotal = document.createElement('div');
        let titleRemaining = document.createElement('div');
        let titleChecked = document.createElement('div');

        switchButton.src = 'http://drug.file.mediportal.com.cn/o_1c461pmm3e265k1a6m19qccso1r';
        switchButton.classList.add("switch-button");

        dataPanel.classList.add("data-panel");
        if (!isExpand) {
            dataPanel.classList.add("data-panel-collapse");
        } else {
            dataPanel.classList.add("data-panel-expand");
        }

        projectsPanel.classList.add("projects-panel");
        if (!isExpand) {
            projectsPanel.classList.add("projects-panel-hidden");
        }

        updateContainer.classList.add("update-container");

        updateTime.id = "time";

        updateButton.textContent = '更新';
        updateButton.id = "button";
        updateButton.classList.add("el-button");
        updateButton.classList.add("btn-size");
        updateButton.classList.add("el-button--primary");

        // 监听点击事件
        switchButton.addEventListener('click', function () {
            togglePanel();
        });

        updateButton.addEventListener('click', function () {
            queryData();
        });

        titleName.textContent = '项目名称';
        titleName.id = 'name';
        titleTotal.textContent = '采集表总数';
        titleTotal.id = "total"
        titleRemaining.textContent = '待审核数';
        titleRemaining.id = 'remaining'
        titleChecked.textContent = '已审核数';
        titleChecked.id = 'checked'

        projectsTitle.classList.add("project-item");
        projectsTitle.classList.add("projects-title");

        projectsTitle.appendChild(titleName);
        projectsTitle.appendChild(titleTotal);
        projectsTitle.appendChild(titleRemaining);
        projectsTitle.appendChild(titleChecked);

        updateContainer.appendChild(updateButton);
        updateContainer.appendChild(updateTime);

        projectsPanel.appendChild(updateContainer);
        projectsPanel.appendChild(projectsTitle);

        dataPanel.appendChild(projectsPanel);
        document.body.appendChild(dataPanel);
        document.body.appendChild(switchButton);
    }

    // 切换面板显示
    function togglePanel() {
        let dom = null;
        if (!isExpand) {
            isExpand = true;
            dom = document.querySelector('.data-panel-collapse');
            dom.classList.remove("data-panel-collapse");
            dom.classList.add("data-panel-expand");
            setTimeout(function () {
                dom = document.querySelector('.projects-panel');
                dom.classList.toggle('projects-panel-hidden');
            }, 300);
        } else {
            isExpand = false;
            setTimeout(function () {
                dom = document.querySelector('.data-panel-expand');
                dom.classList.remove("data-panel-expand");
                dom.classList.add("data-panel-collapse");
            }, 300);
            dom = document.querySelector('.projects-panel');
            dom.classList.toggle('projects-panel-hidden');
            closeDetail();
        }
        saveParams();
        // localStorage.setItem('staticIsExpand', isExpand);
    }

    // 显示/隐藏已审核数量
    function showCheckedCount(project, value) {
        let bar = document.querySelector(`#projectItem-${project.id} #checked .progress-bar`)
        let count = document.querySelector(`#projectItem-${project.id} #checked .checked-count`)
        if (value) {
            bar.style.display = 'none';
            count.style.display = '';
        } else {
            bar.style.display = '';
            count.style.display = 'none';
        }
    }

    // 关闭详细面板
    function closeDetail() {
        let detailPanel = document.querySelector('.detail-panel');
        if (detailPanel) {
            detailPanel.parentNode.removeChild(detailPanel);
        }
    }

    // 打开详细面板
    function openDetail(project) {
        let oldDetailPanel = document.querySelector('.detail-panel');
        let projectPanel = document.createElement('div');
        let nameContainer = document.createElement('div');
        let projectName = document.createElement('div');
        let closeButton = document.createElement('div');
        let detailList = document.createElement('div');
        let detailTitle = document.createElement('div');
        let titlePeriod = document.createElement('div');
        let titleSum = document.createElement('div');
        let detailTotal = document.createElement('div');
        let totalName = document.createElement('div');
        let totalSum = document.createElement('div');

        projectPanel.classList.add("project-panel");

        nameContainer.classList.add("name-container");

        projectName.textContent = project.name;
        projectName.id = "project";

        closeButton.textContent = '✕';
        closeButton.id = "close";

        closeButton.addEventListener('click', function () {
            closeDetail();
        });

        detailList.classList.add("detail-list");

        titlePeriod.textContent = '期间';
        titlePeriod.id = 'period';
        titleSum.textContent = '合计';
        titleSum.id = 'sum'

        detailTitle.classList.add("detail-item");
        detailTitle.classList.add("detail-title");

        totalName.textContent = '累计';
        totalName.id = 'period';
        totalSum.id = 'sum'

        detailTotal.classList.add("detail-item");
        detailTotal.classList.add("detail-total");

        detailTitle.appendChild(titlePeriod);
        detailTitle.appendChild(titleSum);

        detailTotal.appendChild(totalName);
        detailTotal.appendChild(totalSum);

        nameContainer.appendChild(closeButton);
        nameContainer.appendChild(projectName);

        detailList.appendChild(detailTitle);
        detailList.appendChild(detailTotal);

        projectPanel.appendChild(nameContainer);
        projectPanel.appendChild(detailList);

        // 已打开详细面板时复用原有面板避免出现闪动
        if (oldDetailPanel) {
            let detailPanel = oldDetailPanel;
            let oldProjectPanel = detailPanel.querySelector('.project-panel');
            // oldProjectPanel.style.height = '0';
            oldProjectPanel.style.opacity = '0';
            setTimeout(() => {
                detailPanel.removeChild(oldProjectPanel);
                detailPanel.appendChild(projectPanel);
            }, 500)
        } else {
            let detailPanel = document.createElement('div');
            detailPanel.classList.add("detail-panel");
            detailPanel.appendChild(projectPanel);
            detailPanel.style.opacity = '0';
            document.body.appendChild(detailPanel);
            setTimeout(() => {
                detailPanel.style.opacity = '';
            }, 500)
        }

        loadCheckedDetail(project, detailList);
    }

    /* 
     * ================== 查询操作 ==================
     */
    // 查询数据
    function queryData() {
        let now = new Date().getTime();
        // var now = 1684123200000; //5-15
        // var now = 1684555200000; //5-20
        // var now = 1685419200000; //5-30
        // var now = 1686801600000; //6-15
        projects.forEach(project => {
            queryStatic(project);
            if (project.type == 'TAG') {
                querySearch(project);
            }
            // 以当前时间为查询的结束时间
            queryChecked(project, lastUpdateTime || 1672545600000, now);
        });
        lastUpdateTime = now;
        setLastUpdateTime();
        saveParams();
    }

    // 查询统计数据
    function queryStatic(project) {
        let xhr = new XMLHttpRequest();
        let url = 'http://xg.mediportal.com.cn/disease-marketing/case/check/statics/';
        xhr.open('GET', `${url}${project.id}`, true);
        xhr.setRequestHeader('access-token', token);
        xhr.setRequestHeader('userId', userId);

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    const responseData = JSON.parse(xhr.responseText);
                    try {
                        project.base = responseData.data;
                    } catch (e) {
                        project.base = null;
                    }
                } else {
                    project.base = null;
                }
                setTotal(project);
            }
        };

        xhr.send();
    }

    // 查询筛选数据
    function querySearch(project) {
        let xhr = new XMLHttpRequest();
        let url = 'http://xg.mediportal.com.cn/disease-marketing/case/check/search';
        let param = {
            'pageIndex': 0,
            'pageSize': 1,
            'order': 1,
            'sortField': 'createTime',
            'argument': '-1',
            'keyword': '',
            'whiteUser': '-1',
            'checkType': '',
            'patientName': '',
            'patientNumber': '',
            'patientSex': '',
            'hospital': '',
            'nonexistenceAnswerRemark': true,
            'answerRemark': '',
            'departments': '',
            'title': '',
            'checkStatus': '0'
        }
        param.projectId = project.id;

        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
        xhr.setRequestHeader('access-token', token);

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    const responseData = JSON.parse(xhr.responseText);
                    try {
                        project.tag = responseData.data;
                    } catch (e) {
                        project.tag = null;
                    }
                } else {
                    project.tag = null;
                }
                setRemaining(project);
            }
        };

        xhr.send(JSON.stringify(param));
    }

    // 查询审核数据
    function queryChecked(project, beginTime, endTime) {
        // 显示进度条
        showCheckedCount(project, false);
        setCheckedUpdateProgress(project, 0);
        // 调用函数获取全部数据，从第1页开始，每页大小为100
        getAllPagesData(project, 1, 100, beginTime, endTime);

        // 获取当页数据
        function getDataFromPage(project, pageIndex, pageSize, beginTime, endTime) {
            return new Promise((resolve, reject) => {
                let url = 'https://xgdata.mediportal.com.cn/data-external/case/marketing/selectProjectWorkloadByPage';
                url = `${url}?&projectId=${project.id}&pageIndex=${pageIndex}&pageSize=${pageSize}`;
                if (beginTime != 0) {
                    url = `${url}&beginTime=${beginTime}`
                }
                url = `${url}&endTime=${endTime}`
                console.log(url);
                GM_xmlhttpRequest({
                    method: 'GET',
                    url: url,
                    onload: function (response) {
                        if (response.status >= 200 && response.status < 300) {
                            const data = JSON.parse(response.responseText);
                            resolve(data);
                        } else {
                            reject(new Error(`Request failed with status ${response.status}`));
                        }
                    },
                    onerror: function (error) {
                        reject(new Error('Network error'));
                    }
                });
            });
        }

        // 获取所有页数据
        async function getAllPagesData(project, pageIndex, pageSize, beginTime, endTime, allData = []) {
            try {
                const currentPageData = await getDataFromPage(project, pageIndex, pageSize, beginTime, endTime);
                if (currentPageData && currentPageData.data && currentPageData.data.pageData) {
                    console.log(currentPageData);
                    showCheckedCount(project, false);
                    const pageData = currentPageData.data.pageData;
                    allData.push(...pageData);

                    if (currentPageData.data.pageCount > pageIndex) {
                        setCheckedUpdateProgress(project, Math.ceil(pageIndex * 100 / currentPageData.data.pageCount));
                        console.log('Get pages data:', pageIndex);
                        // 如果还有下一页，递归调用继续获取数据
                        return getAllPagesData(project, pageIndex + 1, pageSize, beginTime, endTime, allData);
                    } else {
                        if (allData && allData.length > 0) {
                            // console.log(data);
                            saveChecked(allData);
                        }
                        // 已获取全部数据
                        computeCheckedCount(project);
                        console.log('All pages data:', allData);
                        return allData;
                    }
                } else {
                    // 没有有效数据
                    computeCheckedCount(project);
                    return allData;
                }
            } catch (error) {
                // 请求错误
                computeCheckedCount(project);
                console.error('Error:', error);
                return [];
            }
        }
    }

    // 设置采集表总数
    function setTotal(project) {
        let dom = document.querySelector(`#projectItem-${project.id} #total`);
        if (project.base) {
            dom.textContent = project.base.collectCount;
        } else {
            dom.textContent = '';
        }
        if (project.type === 'CHECK') {
            setRemaining(project);
        }
        saveProjects();
    }

    // 设置待审核数
    function setRemaining(project) {
        let dom = document.querySelector(`#projectItem-${project.id} #remaining`);
        if (project.type === 'TAG' && project.tag) {
            dom.textContent = project.tag.total;
        } else if (project.type === 'CHECK' && project.base) {
            dom.textContent = project.base.leftCount;
        } else {
            dom.textContent = '';
        }
        saveProjects();
    }

    // 设置已审核更新进度
    function setCheckedUpdateProgress(project, progress) {
        if (progress === null || progress === undefined) {
            progress = 100;
        }
        // 更新进度条
        let progressIndicator = document.querySelector(`#projectItem-${project.id} #checked .progress-indicator`);
        progressIndicator.style.width = progress + '%';
    }

    // 设置已审核数
    function setCheckedCount(project) {
        showCheckedCount(project, true);
        let count = document.querySelector(`#projectItem-${project.id} #checked .checked-count`);
        if (project.type === 'CHECK' && project.checked) {
            count.textContent = project.checked.count;
        } else if (project.type === 'TAG' && project.checked) {
            count.textContent = `${project.checked.count} / ${project.checked.tagCount}`;
        } else {
            count.textContent = '';
        }
        saveProjects();
    }

    // 设置最后更新时间
    function setLastUpdateTime() {
        let date = new Date(lastUpdateTime);
        let year = date.getFullYear();
        let month = date.getMonth() + 1; // 月份是从0开始的，所以要加1
        let day = date.getDate();
        let hours = date.getHours();
        let minutes = date.getMinutes();
        let seconds = date.getSeconds();
        let dom = document.querySelector('.update-container #time');
        dom.textContent = `最后更新于：${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    }

    /* 
     * ================== 数据操作 ==================
     */
    // 从数据库读取已审核记录计算已审核数量
    function computeCheckedCount(project) {
        checkedDb.transaction(function (db) {
            db.executeSql('SELECT COUNT(1) count,type FROM checkRecord WHERE projectId = ? GROUP BY type', [project.id], function (db, results) {
                for (let i = 0; i < results.rows.length; i++) {
                    if (results.rows[i].type === '审核病例') {
                        project.checked.count = results.rows[i].count;
                    } else {
                        project.checked.tagCount = results.rows[i].count;
                    }
                };
                setCheckedCount(project);
            }, null);
        });
    }

    // 从数据库加载项目审核记录
    function loadCheckedDetail(project, detailList) {
        checkedDb.transaction(function (db) {
            loadDetailFields(db, project, detailList);
            // 获取月份
            loadDetailPeriod(db, project, detailList, null, 'month', null, detailList.querySelector('.detail-title'), 'week');
            // 获取月份数据
            loadDetailPeriodCount(db, project, detailList, null, 'month', null);
        });
    }

    // 获取动态列
    function loadDetailFields(db, project, detailList) {
        db.executeSql(`SELECT sum(count) count,sum(tagCount) tagCount, sum(total) total, name FROM (
            SELECT CASE type WHEN "审核病例" THEN 1 ELSE 0 END count,
            CASE type WHEN "审核表单" THEN 1 ELSE 0 END tagCount, 
            1 total, name from checkRecord WHERE projectId = ?)
            GROUP BY name ORDER BY total desc`, [project.id], function (db, results) {
            checkRecord['name'] = results.rows;
            let domTitle = detailList.querySelector('.detail-title #sum');
            let domTotal = detailList.querySelector('.detail-total #sum');
            let sumCount = 0, sumTagCount = 0;
            // 按列遍历增加动态列
            for (let i = 0; i < checkRecord['name'].length; i++) {
                let titleName = document.createElement('div');
                let totalName = document.createElement('div');
                titleName.textContent = checkRecord['name'][i].name;
                titleName.classList.add('detail-item-cell');
                domTitle.parentNode.insertBefore(titleName, domTitle);

                // 计算累计值
                let count = checkRecord['name'][i].count;
                let tagCount = checkRecord['name'][i].tagCount;
                sumCount = sumCount + count;
                sumTagCount = sumTagCount + tagCount;
                // 设置已审核数
                if (project.type === 'CHECK') {
                    totalName.textContent = count;
                } else {
                    totalName.innerHTML = `${count}<br>${tagCount}`;
                }
                totalName.classList.add('detail-item-cell');
                domTotal.parentNode.insertBefore(totalName, domTotal);
            }
            // 累计汇总
            if (project.type === 'CHECK') {
                domTotal.textContent = sumCount;
            } else {
                domTotal.innerHTML = `${sumCount}<br>${sumTagCount}`;
            }
        }, null);
    }

    // 获取区间
    function loadDetailPeriod(db, project, detailList, srcPeriodType, destPeriodType, srcPeriod, expandDetailItem, expandPeriodType) {
        let condition = '';
        if (srcPeriodType) {
            condition = ` and ${srcPeriodType}='${srcPeriod}' `
        }
        db.executeSql(`SELECT sum(count) count,sum(tagCount) tagCount, ${destPeriodType} period FROM (
            SELECT CASE type WHEN '审核病例' THEN 1 ELSE 0 END count,
            CASE type WHEN '审核表单' THEN 1 ELSE 0 END tagCount,
            ${destPeriodType} FROM checkRecord WHERE projectId = ? ${condition}) 
            GROUP BY ${destPeriodType}`, [project.id], function (db, results) {
            checkRecord['period'] = results.rows;
            let targetDom = null;
            if (expandDetailItem) {
                targetDom = expandDetailItem.nextSibling;
            }
            // 按行遍历
            for (let i = 0; i < checkRecord['period'].length; i++) {
                let detailItem = document.createElement('div');
                let itemPeriod = document.createElement('div');
                let itemSum = document.createElement('div');

                // 行容器
                detailItem.id = `detailItem-${checkRecord['period'][i].period}`;
                detailItem.classList.add("detail-item");
                detailItem.classList.add(`period-${destPeriodType}`);

                // 行首列
                itemPeriod.textContent = checkRecord['period'][i].period;
                itemPeriod.id = 'period';
                if (expandPeriodType) {
                    itemPeriod.classList.add('not-expand');
                }
                // 行首列绑定点击展开
                itemPeriod.addEventListener('click', function () {
                    // not-expand防止重复加载数据
                    if (itemPeriod.classList.contains('not-expand')) {
                        let nextExpandPeriodType = '';
                        if (expandPeriodType === 'week') {
                            nextExpandPeriodType = 'day';
                        }
                        expandPeriod(project, detailList, destPeriodType, expandPeriodType, itemPeriod.textContent, detailItem, nextExpandPeriodType);
                    }
                });
                detailItem.appendChild(itemPeriod);

                // 按动态列遍历追加单元格
                for (let j = 0; j < checkRecord['name'].length; j++) {
                    let itemName = document.createElement('div');
                    itemName.id = checkRecord['name'][j].name;
                    itemName.classList.add('detail-item-cell');
                    detailItem.appendChild(itemName);
                }

                // 合计
                itemSum.id = 'sum';
                if (project.type === 'CHECK') {
                    itemSum.textContent = checkRecord['period'][i].count;
                } else {
                    itemSum.innerHTML = `${checkRecord['period'][i].count}<br>${checkRecord['period'][i].tagCount}`;
                }
                detailItem.appendChild(itemSum);
                if (!targetDom) {
                    detailList.appendChild(detailItem);
                } else {
                    detailList.insertBefore(detailItem, targetDom);
                }
            }
        }, null);
    }

    // 获取期间数据
    function loadDetailPeriodCount(db, project, detailList, srcPeriodType, destPeriodType, srcPeriod) {
        let condition = '';
        if (srcPeriodType) {
            condition = ` and ${srcPeriodType}='${srcPeriod}' `
        }
        db.executeSql(`SELECT sum(count) count,sum(tagCount) tagCount,${destPeriodType} period,name FROM (
            SELECT CASE type WHEN '审核病例' THEN 1 ELSE 0 END count,
            CASE type WHEN '审核表单' THEN 1 ELSE 0 END tagCount, 
            ${destPeriodType},name FROM checkRecord WHERE projectId = ? ${condition})
            GROUP BY ${destPeriodType},name`, [project.id], function (db, results) {
            for (let i = 0; i < results.rows.length; i++) {
                let row = results.rows[i];
                if (!checkRecord.hasOwnProperty(row.period)) {
                    checkRecord[row.period] = {};
                }
                if (!checkRecord[row.period].hasOwnProperty(row.name)) {
                    checkRecord[row.period][row.name] = {};
                }
                checkRecord[row.period][row.name]['count'] = row.count;
                checkRecord[row.period][row.name]['tagCount'] = row.tagCount;
            };
            for (let i = 0; i < checkRecord['period'].length; i++) {
                for (let j = 0; j < checkRecord['name'].length; j++) {
                    if (checkRecord.hasOwnProperty(checkRecord['period'][i].period)) {
                        let period = checkRecord['period'][i];
                        let name = checkRecord['name'][j];
                        if (checkRecord[period.period].hasOwnProperty(name.name)) {
                            let itemName = detailList.querySelector(`#detailItem-${period.period} #${name.name}`)
                            if (project.type === 'CHECK') {
                                itemName.textContent = checkRecord[period.period][name.name]['count'];
                            } else {
                                itemName.innerHTML = `${checkRecord[period.period][name.name]['count']}<br>${checkRecord[period.period][name.name]['tagCount']}`;
                            }
                        }
                    }
                }
            }
            let itemName = detailList.querySelector(`#detailItem-${srcPeriod} #period`);
            if (itemName) {
                itemName.classList.remove('not-expand');
            }
        }, null);
    }

    // 扩展期间记录
    function expandPeriod(project, detailList, srcPeriodType, destPeriodType, srcPeriod, expandDetailItem, expandPeriodType) {
        checkedDb.transaction(function (db) {
            // 获取周
            loadDetailPeriod(db, project, detailList, srcPeriodType, destPeriodType, srcPeriod, expandDetailItem, expandPeriodType);
            // 获取周数据
            loadDetailPeriodCount(db, project, detailList, srcPeriodType, destPeriodType, srcPeriod);
        });
    }

    // 向数据库保存审核记录
    function saveChecked(data) {
        checkedDb.transaction(function (db) {
            let pIds = new Set();
            for (let i = 0; i < data.length; i++) {
                let record = data[i];
                let pId = projectDesc[record.projectName.replaceAll(' ', '')].id;
                db.executeSql('INSERT INTO checkRecord (projectId, projectName, name, month, week, day, time, type, operate, result) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
                    pId,
                    projectDesc[record.projectName.replaceAll(' ', '')].name,
                    record.userName,
                    record.month,
                    record.week,
                    record.day.split(' ')[0],
                    Date.parse(record.day),
                    record.dataType,
                    record.modifyType,
                    record.opType]);
                pIds.add(pId);
            }
            pIds.forEach(pId => {
                let project = projectIds[pId];
                computeCheckedCount(project);
            });

        });
    }

    // 从数据库加载运行参数
    function loadParams() {
        const transaction = mainDb.transaction("params", "readwrite");
        const objectStore = transaction.objectStore("params");
        const requestGet = objectStore.getAll();

        requestGet.onsuccess = (event) => {
            const result = event.target.result;
            if (result && result.length > 0) {
                let params = {};
                result.forEach(param => {
                    params[param.key] = param.value;
                });
                lastUpdateTime = params["lastUpdateTime"] ?? lastUpdateTime;
                setLastUpdateTime();
                let tmpIsExpand = params["isExpand"] ?? false;
                if (tmpIsExpand != isExpand) {
                    togglePanel();
                }
            }
        };

        requestGet.onerror = (event) => {
            console.error("Error retrieving params:", event.target.error);
        };
    }

    // 向数据库保存运行参数
    function saveParams() {
        const transaction = mainDb.transaction("params", "readwrite");
        const objectStore = transaction.objectStore("params");
        let param = { key: "lastUpdateTime", value: lastUpdateTime };
        objectStore.put(param);
        param = { key: "isExpand", value: isExpand };
        objectStore.put(param);
    }

    // 从数据库加载项目列表
    function loadProjects() {
        const transaction = mainDb.transaction("projects", "readwrite");
        const objectStore = transaction.objectStore("projects");
        const requestGet = objectStore.getAll();

        requestGet.onsuccess = (event) => {
            const result = event.target.result;
            // 读取项目数据
            if (result && result.length > 0) {
                projects = result;
            } else {
                // 缺省项目清单
                projects = [
                    {
                        name: '津力达',
                        id: '6440de96145b67000beae367',
                        desc: '《中华医学杂志》糖尿病健康综合管理促进项目-中成药在糖尿病领域临床应用调研',
                        type: 'TAG',
                        checked: {
                            count: 0,
                            tagCount: 0
                        }
                    },
                    {
                        name: '芪苈强心',
                        id: '64707ad0ccfaec000a6a6a81',
                        desc: '心脑血管疾病防治能力提升项目--真实世界临床调研活动',
                        type: 'TAG',
                        checked: {
                            count: 0,
                            tagCount: 0
                        }
                    },
                    {
                        name: '通心络',
                        id: '647d680eccfaec000a6a742a',
                        desc: '通络药物门诊冠心病临床调研项目',
                        type: 'CHECK',
                        checked: {
                            count: 0,
                            tagCount: 0
                        }
                    },
                    {
                        name: '乡医乡爱',
                        id: '649d5caa449bbb000a0db4f9',
                        desc: '健康中国 赋能县域 “乡”医“乡”爱-我和我的患者故事',
                        type: 'TAG',
                        checked: {
                            count: 0,
                            tagCount: 0
                        }
                    },
                    {
                        name: '万乐',
                        id: '64351ef9496254000b90d90c',
                        desc: '德纳®改善患者微循环的疗效观察的临床应用调研项目',
                        type: 'CHECK',
                        checked: {
                            count: 0,
                            tagCount: 0
                        }
                    },
                    {
                        name: '北陆',
                        id: '64364d9c145b67000beae050',
                        desc: '2023 “护卫身心 玖安无虑” 焦虑患者线上临床调研',
                        type: 'CHECK',
                        checked: {
                            count: 0,
                            tagCount: 0
                        }
                    },
                    {
                        name: '天成',
                        id: '64bf755db33930000a2e570c',
                        desc: '氧疗由你 史无前“例” 首届“天成杯”全国病例大赛暨注射用过氧化碳酰胺临床调研项目第一期',
                        type: 'CHECK',
                        checked: {
                            count: 0,
                            tagCount: 0
                        }
                    },
                ]
                projects.forEach(project => { objectStore.add(project) });
                console.log("projects init");
            }
            // 根据项目名称排序
            projects.sort((a, b) => a.name.localeCompare(b.name));
            // 填充交换界面
            projects.forEach(project => {
                let projectsPanel = document.querySelector('div.projects-panel');
                let projectItem = document.createElement('div');
                let name = document.createElement('div');
                let total = document.createElement('div');
                let remaining = document.createElement('div');
                let checked = document.createElement('div');
                let progressBar = document.createElement('div');
                let progressIndicator = document.createElement('div');
                let count = document.createElement('div');

                projectItem.id = `projectItem-${project.id}`;
                projectItem.classList.add("project-item");

                name.textContent = project.name;
                name.id = 'name';
                total.id = 'total';
                remaining.id = 'remaining';
                checked.id = 'checked';

                progressBar.classList.add('progress-bar');
                progressIndicator.classList.add('progress-indicator');

                count.classList.add('checked-count');
                count.addEventListener('click', function () {
                    checkRecord = {};
                    checkRecord['project'] = project.id;
                    openDetail(project);
                });

                progressBar.appendChild(progressIndicator);

                checked.appendChild(progressBar);
                checked.appendChild(count);

                projectItem.appendChild(name);
                projectItem.appendChild(total);
                projectItem.appendChild(remaining);
                projectItem.appendChild(checked);
                projectsPanel.appendChild(projectItem);

                // 显示已审核数
                showCheckedCount(project, true);

                // 更新映射表
                projectDesc[project.desc.replaceAll(' ', '')] = project;
                projectIds[project.id] = project;

                // 填充数据
                setTotal(project);
                if (project.type == 'TAG') {
                    setRemaining(project);
                }
                computeCheckedCount(project);
            });
        };

        requestGet.onerror = (event) => {
            console.error("Error retrieving projects:", event.target.error);
        };
    }

    // 向数据库保存项目列表
    function saveProjects() {
        const transaction = mainDb.transaction("projects", "readwrite");
        const objectStore = transaction.objectStore("projects");
        projects.forEach(project => { objectStore.put(project) });
    }

    // 加载数据库数据
    function loadDatabase() {
        // 打开或创建IndexedDB数据库
        let requestDB = indexedDB.open('collectionCheck', 1);

        // 当数据库打开或创建成功时执行的回调函数
        requestDB.onsuccess = function (event) {
            mainDb = event.target.result;
            // 数据库操作代码在这里
            loadParams();
            loadProjects();
        };

        // 当数据库打开或创建失败时执行的回调函数
        requestDB.onerror = function (event) {
            console.error('Database error: ' + event.target.errorCode);
        };

        // 第一次创建数据库时，设置数据库结构
        requestDB.onupgradeneeded = function (event) {
            let mainDb = event.target.result;
            let objectStore = mainDb.createObjectStore('params', { keyPath: 'key' });
            objectStore = mainDb.createObjectStore('projects', { keyPath: 'id' });
            objectStore.createIndex('nameIndex', 'name', { unique: true });
            objectStore.createIndex('descIndex', 'desc', { unique: true });
            objectStore.createIndex('typeIndex', 'type', { unique: false });
            console.log('数据库创建结束');
        };

        // 打开WebSQL数据库：
        checkedDb = openDatabase('collectionCheck', '1.0', 'Checked DB', 1 * 1024 * 1024);
        checkedDb.transaction(function (db) {
            db.executeSql(`CREATE TABLE IF NOT EXISTS checkRecord (
                                id INTEGER PRIMARY KEY, 
                                projectId TEXT, 
                                projectName TEXT,
                                name TEXT, 
                                month TEXT, 
                                week TEXT, 
                                day TEXT, 
                                time DATETIME, 
                                type TEXT, 
                                operate TEXT, 
                                result TEXT)`);
        });
    }

    /* 
     * ================== 初始化 ==================
     */
    let mainDb = null;
    let checkedDb = null;
    let lastUpdateTime = 0;
    let isExpand = false;
    let projects = [];
    let projectIds = {};
    let projectDesc = {};
    let checkRecord = {};
    // 载入本地存储数据
    let token = '';
    let userId = '';
    if (localStorage.getItem('ysf-case-pc-token')) {
        token = localStorage.getItem('ysf-case-pc-token').replaceAll('"', '');
    }
    if (localStorage.getItem('ysf-case-pc-userInfo')) {
        userId = localStorage.getItem('ysf-case-pc-userInfo').userId;
    }

    // 显示面板
    showPanel();
    // 面板加载数据
    loadDatabase();

})();